#include "shape.h"

Shape::~Shape() {
	material = NULL;
}

Shape::Shape(const Transform *o2w, const Transform *w2o, bool ro, Reference<Material> mat) :
	ObjectToWorld(o2w), WorldToObject(w2o), ReverseOrientation(ro), 
		TransformSwapsHandedness(o2w->SwapHandedness()), shapeId(nextshapeId++), arealight(NULL) {
	material = mat;
}

BSDF *Shape::GetBSDF(const Intersection &isect) const {
	GetShadingGeometry(isect);
	return material->GetBSDF(isect);
}

BBox Shape::WorldBound() const {
	return (*WorldToObject)(ObjectBound());
}

bool Shape::Intersect(const Ray &ray, Intersection *isect) const {
	Fatal("Unimplemented Shape::Intersect() method called");
	return false;
}

bool Shape::IntersectP(const Ray &ray) const {
	Fatal("Unimplemented Shape::IntersectP() method called");
	return false;
}

void Shape::FillIntersection(const Ray &ray, Intersection *isect) const {
	Fatal("Unimplemented Shape::FillIntersection() method called");
	return;
}
float Shape::Area() const {
	Fatal("Unimplemented Shape::Area() method called");
	return 0.;
}

float Shape::Pdf(const Point3 &p, const Vector3 &wi) const {
	// Intersect sample ray with area light geometry
	Intersection isect;
	Ray ray(p, wi);
	ray.depth = -1;	// temporary hack to ignore alpha mask
	if(!Intersect(ray, &isect))
		return 0.;
	// dw = dA * costheta / r^2
	// pdf w.r.t dA = 1.f / area
	// pdf w.r.t dw = dA * r^2 / costheta
	float pdf = DistanceSqured(p,ray(isect.t)) / (AbsDot(isect.geometryFrame.n, -wi) * Area());
	if(isinf(pdf))
		pdf = 0.f;
	return pdf;
}

uint32_t Shape::nextshapeId = 1;